package com.edu.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.edu.service.FileService;
import com.edu.util.IOHelper;
import com.edu.vo.FileMeta;
import com.edu.vo.ResultVO;


@Controller
@RequestMapping("/files")
public class FileUploadController {

	private LinkedList<FileMeta> files = new LinkedList<FileMeta>();
	private FileMeta fileMeta = null;
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private FileService fileService;
	
	@Value("#{prop.upload}")
	private String upload;

	
	@RequestMapping(value = "jqueryFileUploadDemo", method = RequestMethod.GET)
	public String index() {
		return "upload";
	}
	
	
	/***************************************************
	 * URL: /files/upload upload(): receives files
	 * 
	 * @param request
	 *            : MultipartHttpServletRequest auto passed
	 * @param response
	 *            : HttpServletResponse auto passed
	 * @return LinkedList<FileMeta> as json format
	 ****************************************************/
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	public @ResponseBody LinkedList<FileMeta> upload(MultipartHttpServletRequest request,
			HttpServletResponse response) {

		// 1. build an iterator
		Iterator<String> itr = request.getFileNames();
		MultipartFile mpf = null;

		// 2. get each file
		while (itr.hasNext()) {

			// 2.1 get next MultipartFile
			mpf = request.getFile(itr.next());
			System.out.println(mpf.getOriginalFilename() + " uploaded! " + files.size());

			// 2.2 if files > 10 remove the first from the list
			if (files.size() >= 10)
				files.pop();

			// 2.3 create new fileMeta
			fileMeta = new FileMeta();
			fileMeta.setFileName(mpf.getOriginalFilename());
			fileMeta.setFileSize(mpf.getSize() / 1024 + " Kb");
			fileMeta.setFileType(mpf.getContentType());

			try {
				fileMeta.setBytes(mpf.getBytes());

				// copy file to local disk (make sure the path "e.g. D:/temp/files" exists)
				FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(upload+ File.separator + mpf.getOriginalFilename()));

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 2.4 add to files
			files.add(fileMeta);
		}
		// result will be like this
		// [{"fileName":"app_engine-85x77.png","fileSize":"8
		// Kb","fileType":"image/png"},...]
		return files;
	}

	/***************************************************
	 * URL:
	 * 
	 * @param response
	 *            : passed by the server
	 * @param value
	 *            : value from the URL
	 * @return void
	 ****************************************************/
	@RequestMapping(value = "/download", method = RequestMethod.GET)
	public void download(HttpServletResponse response, @RequestParam(value = "name") String name) {

		File file = fileService.getFileByName(name);
		ServletOutputStream outputStream = null;
		try {
			byte[] fileBytes = IOHelper.fileToBytes(file);
			logger.debug(fileBytes.toString());
			response.setContentType("application/octet-stream");
			response.setHeader("Content-disposition", "attachment; filename=\"" + file.getName() + "\"");
			response.addHeader("Content-Length", "" + file.length());
			outputStream = response.getOutputStream();
			outputStream.write(fileBytes);
			outputStream.flush();
		} catch (IOException e) {
			e.printStackTrace();
			logger.debug(e.getMessage());			
		}finally {
			try {
				outputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
